from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.http import HttpResponse
from django.http import HttpResponseForbidden
from django.http import HttpResponsePermanentRedirect
from django.http import JsonResponse
from django.shortcuts import render
from django.urls import reverse
from django.views import View
from django.contrib.auth import login,logout

from boxuegu.settings import logger
from courses.models import Course
from operation.models import UserCourse, UserFavorite, UserMessage
from organization.models import CourseOrg, Teacher
from users.forms import RegisterForm, LoginForm, ForgetForm, UserInfoForm, UploadImageForm, ModifyPwdForm
from users.models import UserProfile, Banner
from utils.mixin_utils import LoginRequiredMixin

# 用户消息(分页)
class MyMessageView(View):

    def get(self,request):

        user = request.user
        # 获取所有消息
        usermessages = UserMessage.objects.filter(user=user.id).all()
        # 获取消息的个数
        message_nums = usermessages.count()
        # 获取当前页数
        page = request.GET.get('page', 1)
        # 创建分页器
        paginator = Paginator(usermessages, 2)

        try:
            # 获取当前页的数据
            messages = paginator.page(page)
        except PageNotAnInteger:
            messages = paginator.page(1)
        except EmptyPage:
            messages = paginator.page(paginator.num_pages)






        # 创建分页器：每页N条记录
        # paginator = Paginator(usermessages, 2)
        # # 获取当前页的数据
        # paginator.page(1)
        # # 获取列表总页数
        # pages = paginator.num_pages
        #
        # messages = [{'messages': , 'pages': , 'has_next': , 'next_page_number':}]

        return render(request, 'usercenter-message.html', {
            'messages': messages,
        })


# 我的收藏 公开课程
class MyFavCourseView(View):

    def get(self, request):

        user = request.user

        course_list = []
        # 取出收藏的所有公开课程的id对象
        course_ids = UserFavorite.objects.filter(user=user,fav_type=1)

        for course in course_ids:
            course_id = course.fav_id
            # 根据收藏的公开课id取出公开课的对象
            course = Course.objects.get(id=course_id)

            course_list.append({
                'course_id': course_id,
                'course': course
            })

        return render(request, 'usercenter-fav-course.html', {
            'course_list': course_list,
        })

# 我的收藏 授课讲师
class MyFavTeacherView(View):

    def get(self, request):
        # [
        #     {
        #         'teacher_id': 收藏教师的id
        #         'teacher': 收藏教师对像（Teacher类）
        # }，
        # {
        #     'teacher_id': 收藏教师的id
        #     'teacher': 收藏教师对像（Teacher类）
        # }，
        # ]
        user = request.user

        teacher_list = []
        # 取出所有收藏的老师id对象
        teacher_ids = UserFavorite.objects.filter(user=user,fav_type=3)
        # 遍历
        for teacher in teacher_ids:
            teacher_id = teacher.fav_id

            # 在Teacher表中取出老师的对象
            teacher = Teacher.objects.get(id=teacher_id)
            # 追加到列表中，构建数据格式
            teacher_list.append({
                'teacher_id': teacher_id,
                'teacher': teacher
            })


        return render(request, 'usercenter-fav-teacher.html', {
            'teacher_list': teacher_list,
        })


# 我的收藏 课程学校
class MyFavOrgView(View):

    def get(self,request):
        # org_list数据形式，
        # [
        #     {
        #         'org_id': 收藏学校的id
        #         'org': 课程学校对像（CourseOrg对象）
        # }，
        # {
        #     'org_id': 收藏学校的id
        #     'org': 课程学校对象（CourseOrg类对象）
        # }，
        # ]

        user = request.user
        org_list = []
        # 取出当前用户的收藏对象
        # fav = UserFavorite.objects.get(user=user)
        # # 收藏的所有学校的id
        # org_ids = [fav.fav_id]
        # 取出收藏的所有学校id的对象
        org_ids = UserFavorite.objects.filter(user=user,fav_type=2)
        # 遍历
        for org_id in org_ids:
            org_id = org_id.fav_id
            # 课程学校对象
            org = CourseOrg.objects.get(id=org_id)
            # 追加到列表中，构建数据格式
            org_list.append({
                'org_id': org_id,
                'org': org
            })


        return render(request, 'usercenter-fav-org.html', {
            'org_list': org_list,
        })



# 我的 课程
class MyCourseView(LoginRequiredMixin,View):

    def get(self,request):

        user = request.user
        user_courses = UserCourse.objects.filter(user=user).all()



        return render(request, 'usercenter-mycourse.html', {
            'user_courses': user_courses,
        })



# 修改头像*
class UploadImageView(LoginRequiredMixin,View):

    def post(self,request):

        # 接收头像图片参数
        # data = request.POST
        # uploadimage_form = UploadImageForm(data)
        #
        # res = uploadimage_form.is_valid()
        #
        # user = request.user
        #
        # if res:
        #
        #     image = uploadimage_form['image']
        #
        #     try:
        #         user.image = image
        #         user.save()
        #     except Exception as e:
        #         return JsonResponse({"status":"error", "msg":'头像修改失败'})
        #
        #
        #     return JsonResponse({"status":"success", "msg":'头像修改成功'})
        #
        # return JsonResponse({"status": "error", "msg": '头像修改失败'})

        image_form = UploadImageForm(request.POST, request.FILES, instance=request.user)

        if image_form.is_valid():

            image_form.save()

            return JsonResponse({"status":"success", "msg":'头像修改成功'})

        return JsonResponse({"status": "error", "msg": '头像修改失败'})


# 用户中心
class UserInfoView(LoginRequiredMixin,View):
    # 用户中心页面
    def get(self,request):

        return render(request, 'usercenter-info.html')

    # 修改用户中心信息功能
    def post(self,request):
        # 1. 获取前端传递的表单数据
        data = request.POST
        # 2. 验证表单数据
        userinfo_form = UserInfoForm(data)
        # 验证成功返回True，验证失败返回False
        res = userinfo_form.is_valid()

        user = request.user

        if res:

            nick_name = userinfo_form.cleaned_data['nick_name']
            gender = userinfo_form.cleaned_data['gender']
            birthday = userinfo_form.cleaned_data['birthday']
            address = userinfo_form.cleaned_data['address']
            mobile = userinfo_form.cleaned_data['mobile']

            # 将表单信息更新到数据库
            try:
                # UserProfile.objects.get(username=email).update(
                #     nick_name=nick_name,
                #     gender=gender,
                #     birthday=birthday,
                #     address=address,
                #     mobile=mobile
                # )

                user.nick_name=nick_name
                user.gender=gender
                user.birthday=birthday
                user.address=address
                user.mobile=mobile
                user.save()

            except Exception as e:
                return JsonResponse({"status":"error"})

            return JsonResponse({"status":"success"})

        return JsonResponse({"status":"error"})

# 修改密码
class ResetView(View):
    # 解密路径参数，验证用户，返回修改密码的页面
    def get(self,request,active_code):

        # 参数解密
        from utils.secret import SecretOauth
        code_dict = SecretOauth().loads(active_code)
        # 接收参数
        email = code_dict['email']
        user_id = code_dict['user_id']
        #验证该用户是否存在
        try:
            user = UserProfile.objects.get(id=user_id)
        except Exception as e:
            # 如果不存在
            return render(request, 'active_fail.html')
        # 存在
        return render(request, 'password_reset.html', {'email': email})

    # 实现修改密码功能
    def post(self, request, active_code):


        user = request.user
        # 1. 获取前端传递的表单数据
        data = request.POST
        # 2. 验证表单数据
        modifypwd_form = ModifyPwdForm(data)
        # 验证成功返回True，验证失败返回False
        res = modifypwd_form.is_valid()

        if res:

            password1 = modifypwd_form.cleaned_data['password1']
            password2 = modifypwd_form.cleaned_data['password2']
            # 比较两次密码是否相同
            if password1 == password2:
                try:
                    # 更新用户数据的密码
                    user.set_password(password2)
                    user.save()
                except:
                    return HttpResponseForbidden('修改密码失败')
                # 修改成功重定向到登录页
                return HttpResponsePermanentRedirect(reverse('login'))

            return HttpResponseForbidden('修改密码失败')


# 忘记密码
class ForgetPwdView(View):
# 忘记密码页面的展示
    def get(self,request):
        forget_form = ForgetForm()
        return render(request, 'forgetpwd.html', {'forget_form': forget_form})
    # 忘记密码的功能实现，发送更改密码的邮件
    def post(self,request):
        # 1.接收参数
        data = request.POST

        # 2. 验证表单数据
        forget_form = ForgetForm(data)
        # 验证成功返回True，验证失败返回False
        res = forget_form.is_valid()

        if res:
            # 获取email字段
            email = forget_form.cleaned_data['email']
            try:
                # 查询数据库是否存在该用户
                user = UserProfile.objects.get(username=email)
            except Exception as e:
                # 如果不存在，依然返回忘记密码的页面
                logger.error(e)
                return render(request, 'forgetpwd.html', {'forget_form': forget_form})

            # 修改密码的网址拼接加密
            from .utils import generate_reset_email_url
            reset_url = generate_reset_email_url(user)

            # 发送邮件
            from utils.sendemail import send_reset_email
            send_reset_email(email, reset_url)

            # 返回渲染的邮箱发送成功页面
            return render(request, 'send_success.html')
        # 如果验证失败，返回忘记密码的页面
        return render(request, 'forgetpwd.html', {'forget_form': forget_form})


# 首页展示
class IndexView(View):

    def get(self,request):

        # return render(request, 'index.html')
        # all_banners 获取轮播图表(Banner)所有轮播图数据
        # courses  获取课程信息表(Course)中的课程信息数据
        # banner_courses 获取课程信息表中(Course)的课程信息数据 和上面数据一样
        # course_orgs  获取课程学校表(CourseOrg)中的数据

        all_banners = Banner.objects.all()
        courses = Course.objects.all()
        banner_courses = Course.objects.all()
        course_orgs = CourseOrg.objects.all()


        return render(request, 'index.html', {
            'all_banners': all_banners,
            'courses': courses,
            'banner_courses': banner_courses,
            'course_orgs': course_orgs,
        })


# 退出登录
class LogoutView(View):

    def get(self, rerquest):

        return HttpResponsePermanentRedirect(reverse('login'))


# 登录功能
class LoginView(View):
    # 得到登录的页面
    def get(self,request):

        return render(request,'login.html')
    # 实现登录的功能
    def post(self,request):

        # 接收参数
        data = request.POST
        # 验证参数
        login_form = LoginForm(data)
        # 验证成功过返回True
        res = login_form.is_valid()

        if res:
            # 获取username的字段
            username = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']
            # # 查询数据库是否存在该用户
            # try:
            #     user = UserProfile.objects.get(username=username)
            # except Exception as e:
            #     # 用户不存在返回登录页面
            #     return render(request, 'login.html', {'form_errors': login_form.errors})
            # 3. 验证用户名和密码---django自带的认证
            from django.contrib.auth import authenticate, login
            # 返回的是一个user对象
            user = authenticate(username=username, password=password)

            if user is None:
                # return render(request, 'login.html', {'form_errors': login_form.errors})
                return HttpResponseForbidden('登录失败')
            # 保持登录状态
            login(request,user)
            # 重定向到首页
            return HttpResponsePermanentRedirect(reverse('index'))

        # return render(request, 'login.html', {'form_errors': login_form.errors})
        return HttpResponseForbidden('登录失败')


#  注册功能
class RegisterView(View):

    # 获取注册页面
    def get(self,request):
        # 生成表单对象
        register_form = RegisterForm()

        return render(request, 'register.html', {'register_form': register_form})

    # 注册功能
    def post(self,request):

        # 1. 获取前端传递的表单数据
        data = request.POST
        # 2. 验证表单数据
        register_form = RegisterForm(data)
        # 验证成功返回True，验证失败返回False
        res = register_form.is_valid()

        if res:
            # 获取验证成功后的字段
            email = register_form.cleaned_data['email']
            password = register_form.cleaned_data['password']

            try:
                # 将注册的用户信息保存到数据库
                user = UserProfile.objects.create_user(
                    username=email,
                    email=email,
                    password=password
                )
            except Exception as e:
                return HttpResponse('注册失败')
            # 注册成功保持登录状态
            login(request, user)
            # 重定向到首页
            return HttpResponsePermanentRedirect(reverse('index'))



        return render(request, 'register.html', {'form_errors': register_form.errors})



